/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package digitaldreamers.games.ddmonsters.servers.gameserver.components;

import digitaldreamers.games.ddmonsters.servers.gameserver.data.FacadeDataHandler;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Random;

/**
 * Information of a deck of a player.
 * @author DaoLe
 */
public class DeckComponent
{
    private static final String CARD_IS_NULL_ERROR_MESSAGE = "Card can not be null.";
    private static int MAX_NUMBER_OF_CARDS = 40;
    private static int SHUFFLING_TIMES_AT_START = 1;
    
    private int m_iDeckNumber;//The deck number.
    private PlayerComponent m_Owner;//Refer to the owner of the deck.
    private ArrayList<PlayerCardComponent> m_CardList;//The cards in the deck.
    private ArrayList<PlayerCardComponent> m_CardToPlayList;//The copy of the deck. This is for duel time only.
    private FacadeDataHandler m_DataHandler;
    private Random m_Random;//A random object for shuffling the deck.
    
    /**
     * Get the deck number.
     * @return The deck number.
     */
    public int getDeckNumber()
    {
        return m_iDeckNumber;
    }
    
    /**
     * Get the number of cards in the deck.
     * @return The number of cards in the deck.
     */
    public int getQuantity()
    {
        return m_CardList.size();
    }
    
    public int getQuantityInDuel() {
        return m_CardToPlayList.size();
    }
    
    /**
     * Get The owner of the deck.
     * @return The owner of the deck.
     */
    public PlayerComponent getOwner()
    {
        return m_Owner;
    }
    
    public PlayerCardComponent getCardByID(int iID) {
        for(PlayerCardComponent card : m_CardList) {
            if (card.getID() == iID) {
                return card;
            }
        }
        return null;
    }
    
    /**
     * Create an instance of a deck.
     * @param iDeckNumber The deck number.
     * @param owner The owner of the deck.
     * @param dataHandler The data handler.
     */
    public DeckComponent(int iDeckNumber, PlayerComponent owner, FacadeDataHandler dataHandler)
    {
        m_iDeckNumber = iDeckNumber;
        m_Owner = owner;
        m_CardList = new ArrayList<>();
        m_CardToPlayList = new ArrayList<>();
        m_DataHandler = dataHandler;
        m_Random = new Random();
    }
    
    /**
     * Prepare the deck for duel.
     */
    public void prepareForDuel()
    {
        m_CardToPlayList.clear();//Clear the copy deck.
        m_CardToPlayList.addAll(m_CardList);//Add cards to the copy deck.
        shuffle(SHUFFLING_TIMES_AT_START);//Shuffle the copy deck.
    }
    
    /**
     * Draw the top card of the deck.
     * @return The top card of the deck.
     * @throws IndexOutOfBoundsException If there is no card to draw.
     */
    public PlayerCardComponent drawCard()
    {
        if(m_CardToPlayList.size() <= 0) {
            return null;
        }
        return m_CardToPlayList.remove(m_CardToPlayList.size() - 1);
    }
    
    /**
     * Shuffle the deck.
     * @param repeat The number of times to shuffle.
     */
    public void shuffle(int iRepeat)
    {
        if (iRepeat > 0 && m_CardToPlayList.size() > 0) {
            int iCard1;
            int iCard2;
            PlayerCardComponent swap;
            for (int i = 0; i < m_CardToPlayList.size() * iRepeat; i++) {
                iCard1 = m_Random.nextInt(m_CardToPlayList.size());
                iCard2 = m_Random.nextInt(m_CardToPlayList.size());
                swap = m_CardToPlayList.get(iCard1);
                m_CardToPlayList.set(iCard1, m_CardToPlayList.get(iCard2));
                m_CardToPlayList.set(iCard2, swap);
            }
        }
    }
    
    /**
     * Add a card to the deck.
     * @param card The card to add.
     * @throws IllegalArgumentException If the card to add is null.
     * @throws IndexOutOfBoundsException If the deck already has 40 cards.
     */
    public synchronized boolean addCardToDeck(PlayerCardComponent card) throws IllegalArgumentException, IndexOutOfBoundsException
    {
        if(card == null) {
            throw new IllegalArgumentException(CARD_IS_NULL_ERROR_MESSAGE);
        }
        if(m_CardList.size() >= MAX_NUMBER_OF_CARDS) {
            return false;
        }
        return m_CardList.add(card);
        //Update database
    }
    
    /**
     * Remove a card from the deck.
     * @param card The card to remove.
     * @throws IllegalArgumentException If the card to remove is null.
     */
    public synchronized boolean removeCardFromDeck(PlayerCardComponent card) throws IllegalArgumentException
    {
        if(card == null) {
            throw new IllegalArgumentException(CARD_IS_NULL_ERROR_MESSAGE);
        }
        return m_CardList.remove(card);
        //Update database
    }
    
    public void loadCards() throws SQLException {
        /*
        try {
            m_CardList = m_DataHandler.loadCardsForADeck(m_Owner);
        } catch (SQLException ex) {
            throw ex;
        }
        */
    }
}
